; codigo_t * generar_tabla_codigos(unsigned int *tabla_apariciones);

%include "macros/personalizada.mac"

extern liberar_arbol
extern crear_lista_huffman
extern crear_arbol_huffman
extern generar_codigo
extern calloc
extern free

global generar_tabla_codigos

%define ptr_tabla_codigos [ebp - 16]
%define ptr_arbol [ebp - 12]
%define ptr_indice_nodos [ebp - 8]
%define ptr_lista [ebp - 4]
%define ptr_tabla [ebp + 8]

section .text

generar_tabla_codigos:
	push ebp
	mov ebp, esp
	sub esp, 16
	push esi
	push edi
	push ebx
	
	;Limpio los valores de los punteros
	mov dword ptr_tabla_codigos, 0
	mov dword ptr_arbol, 0
	mov dword ptr_indice_nodos, 0
	mov dword ptr_lista, 0
	
	; Reservamos memoria para la tabla de 256 posiciones de ptr_indice_nodos para crear lista huffman.
	mov ebx, 4
	mov eax, 256
	push ebx
	push eax
	call calloc
	add esp, 8
	
	cmp eax, 0
	je NEAR fin
		
		
	; Creamos la lista de huffman.
	; void crear_lista_huffman(unsigned int *tabla_apariciones, nodo_lista_t **l, nodo_arbol_t **indices_nodos_simbolos);
	mov ptr_indice_nodos, eax
	lea ebx, ptr_lista
	mov esi, ptr_tabla
	push eax
	push ebx
	push esi
	call crear_lista_huffman
	add  esp, 12
	
	; Creamos el arbol de Huffman.
	; void crear_arbol_huffman(nodo_lista_t **l, nodo_arbol_t **a);
	lea eax, ptr_arbol
	lea ebx, ptr_lista
	push eax
	push ebx
	call crear_arbol_huffman
	add esp, 8
	mov eax, ptr_arbol ; Me fijo si pudo crear el arbol de huffman.
	cmp eax, 0
	je NEAR error
	
	; Reservamos memoria para la tabla de codigos.
	mov ebx, 16
	mov eax, 256
	push ebx
	push eax
	call calloc
	add esp, 8
	cmp eax, 0
	je fin
	
	mov ptr_tabla_codigos, eax
	
	mov ecx, 256 ; Cantidad de iteraciones.
	mov esi, ptr_arbol ; Puntero arbol de Huffman.
	mov edi, ptr_indice_nodos ; Puntero a tabla de puntero a hojas.
	
ciclo:
	shl ecx, 4 ; Multiplicamos ecx * 16.
	lea eax, [eax + ecx - 16] ; Posicionamos el puntero de la tabla codigos.
	shr ecx, 4
	
	push ecx
	
	mov ebx, [edi + ecx * 4 - 4] ; ebx = puntero a hoja actual.
	cmp ebx, 0 ; Nos fijamos que el puntero a hoja no sea NULL.
	je siguiente
	
	; Generamos el codigo de la hoja.
	; int generar_codigo(nodo_arbol_t *a, nodo_arbol_t *h, codigo_t *c);
	push eax ; eax = puntero a tabla de codigo (pos actual)
	push ebx
	push esi
	call generar_codigo
	add esp, 12
	cmp eax, 0
	jne error
	
siguiente:
	pop ecx
	mov eax, ptr_tabla_codigos ; Restauramos el puntero a la tabla de codigos.
	
	loop ciclo
	
	; Liberamos la memoria del arbol de huffman.
	mov eax, ptr_arbol ; Puntero arbol de Huffman.
	push eax
	call liberar_arbol
	add esp, 4

	; Liberamos la memoria de la lista de nodos.
	mov eax, ptr_indice_nodos
	push eax
	call free
	add esp,4
	
	mov eax, ptr_tabla_codigos	;devolvemos el ptr a tabla codigos
	jmp fin
	
error:
	mov eax, error_code
	
fin:
	pop ebx
	pop edi
	pop esi
	add esp, 16
	pop ebp
	ret
